package com.example.oauth2.config;

import com.example.oauth2.component.CustomOpaqueTokenIntrospector;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.AbstractRequestMatcherRegistry;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.config.annotation.web.configurers.oauth2.server.resource.OAuth2ResourceServerConfigurer;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.oauth2.server.resource.introspection.OpaqueTokenIntrospector;
import org.springframework.security.web.SecurityFilterChain;

/**
 * @author <a href="nav1cat@outlook.com">nav1c</a>
 * @apiNote
 * @date 2023-12-18 19:57:48
 * @project study-cloud
 * @kit IntelliJ IDEA
 */
@EnableGlobalMethodSecurity(prePostEnabled = true)
@Configuration
public class ResourceServerConfig {

    public static final int RESOURCE_SERVER_FILTER_ORDER = 100;

    @Bean
    @Order(RESOURCE_SERVER_FILTER_ORDER)
    public SecurityFilterChain resourceServerFilterChain(HttpSecurity http) throws Exception {
        http.oauth2ResourceServer(oAuth2ResourceServerConfigurerCustomizer());
        http.securityMatchers(AbstractRequestMatcherRegistry::anyRequest)
                .authorizeHttpRequests(registry ->
                        registry.requestMatchers("/permit/**").permitAll()
                                .requestMatchers("/deny/**").denyAll()
                                .requestMatchers("/remember-me/**").rememberMe()
                                .requestMatchers("/anonymous/**").anonymous()
                                .anyRequest().authenticated());
        http.csrf(AbstractHttpConfigurer::disable);
        http.sessionManagement(configurer ->
                configurer.sessionCreationPolicy(SessionCreationPolicy.STATELESS));
        return http.build();
    }

    @Bean
    public Customizer<OAuth2ResourceServerConfigurer<HttpSecurity>> oAuth2ResourceServerConfigurerCustomizer(){
        return configurer ->
                configurer.opaqueToken(opaqueTokenConfigurer ->
                        opaqueTokenConfigurer.introspector(opaqueTokenIntrospector()));
//                                        .introspectionUri(opaquetoken.getIntrospectionUri())
//                                        .introspectionClientCredentials(opaquetoken.getClientId(), opaquetoken.getClientSecret()))
    }

    @Bean
    public OpaqueTokenIntrospector opaqueTokenIntrospector() {
        return new CustomOpaqueTokenIntrospector("http://localhost:8080/oauth2/introspect", "oauth2", "123");
    }

}
